// $Id: wfc.c 68 2012-07-20 04:15:12Z alan.watson.f $

#define _POSIX_C_SOURCE 200112L

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>

#include "oaxaca-config.h"
#include "oaxaca.h"
#include "adaptica.h"

////////////////////////////////////////////////////////////////////////////////

int
oaxaca_wfc_initialized(void)
{
  return oaxaca_shm != NULL && oaxaca_shm->wfc.initialized;
}

char
oaxaca_wfc_command(void)
{
  if (oaxaca_shm == NULL)
    return 0;
  else
    return oaxaca_shm->wfc.command;
}

void
oaxaca_wfc_set_command(char command)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfc.command = command;
}

int
oaxaca_wfc_modal(void)
{
  if (oaxaca_shm == NULL)
    return 0;
  else
    return oaxaca_shm->wfc.modal;
}

void
oaxaca_wfc_set_modal(int modal)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfc.modal = modal;
}

unsigned long
oaxaca_wfc_cycle(void)
{
  if (oaxaca_shm == NULL)
    return 0;
  else
    return oaxaca_shm->wfc.cycle;
}

double
oaxaca_wfc_voltage(unsigned int i)
{
  if (oaxaca_shm != NULL && i < OAXACA_WFC_NV)
    return oaxaca_shm->wfc.v[i];
  else
    return 0.0;
}

void
oaxaca_wfc_set_voltage(unsigned int i, unsigned char v)
{
  if (oaxaca_shm != NULL && i < OAXACA_WFC_NV)
    oaxaca_shm->wfc.v[i] = v;
}

double
oaxaca_wfc_mode(unsigned int i)
{
  if (oaxaca_shm != NULL && i < OAXACA_WFC_NMODE)
    return oaxaca_shm->wfc.mode[i];
  else
    return 0.0;
}

void
oaxaca_wfc_set_mode(unsigned int i, double v)
{
  if (oaxaca_shm != NULL && i < OAXACA_WFC_NMODE)
    oaxaca_shm->wfc.mode[i] = v;
}

////////////////////////////////////////////////////////////////////////////////

void
oaxaca_wfc_main(void)
{
  oaxaca_common_main("wfc");
  oaxaca_initialized = &oaxaca_shm->wfc.initialized;

  oaxaca_info("initializing wfc hardware.");
  oaxaca_adaptica_initialize();

  oaxaca_shm->wfc.initialized = 0;
  oaxaca_shm->wfc.command     = 'i';
  oaxaca_shm->wfc.modal       = 0;
  oaxaca_shm->wfc.cycle       = 0;
  for (int i = 0; i < OAXACA_WFC_NV; ++i)
    oaxaca_shm->wfc.v[i] = 0;
  for (int i = 0; i < OAXACA_WFC_NMODE; ++i)
    oaxaca_shm->wfc.mode[i] = 0;
  oaxaca_adaptica_set_voltages();
  oaxaca_shm->wfc.initialized = 1;
    
  oaxaca_info("starting command loop.");

  for (;;) {
    int command = oaxaca_shm->wfc.command;
    switch (command) {
    case 'i': // start idling
      oaxaca_shm->wfc.cycle = 0;
      oaxaca_shm->wfc.command = 'I';
      break;
    case 'I': // continue idling
      break;    
    case 'r': // start running free
      oaxaca_shm->wfc.command = 'R';
      oaxaca_adaptica_set_voltages();
      ++oaxaca_shm->wfc.cycle;
      break;
    case 'R': // continue running free
      oaxaca_adaptica_set_voltages();
      ++oaxaca_shm->wfc.cycle;
      break;
    case 't': // trigger
      oaxaca_adaptica_set_voltages();
      ++oaxaca_shm->wfc.cycle;
      oaxaca_shm->wfc.command = 'I';
      break;
    default:
      oaxaca_error("unrecognized command \'%c\'.", command);
      break;
    }
    oaxaca_usleep(20);
  }
  
  oaxaca_error("command loop terminated.");
}

////////////////////////////////////////////////////////////////////////////////